/*
 * @Author: your name
 * @Date: 2021-01-15 13:14:34
 * @LastEditTime: 2021-01-21 17:22:01
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \easycmsboot\src\main\java\com\easycms\service\system\SysMenuService.java
 */
package com.easycms.web.system.service;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.easycms.cache.PermissionCache;
import com.easycms.common.CommonUtil;
import com.easycms.common.IdHelper;
import com.easycms.framework.domain.KeyValueInt64Dto;
import com.easycms.framework.exception.EasyException;
import com.easycms.web.system.domain.SysMenu;
import com.easycms.web.system.domain.SysOperate;
import com.easycms.web.system.domain.SysRoleAuthorize;
import com.easycms.web.system.mapper.SysMenuMapper;
import com.easycms.web.system.mapper.SysOperateMapper;
import com.easycms.web.system.mapper.SysRoleAuthorizeMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;
import com.easycms.web.system.dto.*;
import org.springframework.transaction.annotation.Transactional;

@Service
public class SysMenuService{

    @Autowired
    SysMenuMapper menuMapper;
    @Autowired
    SysOperateMapper operateMapper;
    @Autowired
    SysRoleAuthorizeMapper roleAuthorizeMapper;

    public List<SysMenu> getAllMenus(){


        QueryWrapper<SysMenu> query=new QueryWrapper<>();
         //query.eq("menu_type",1)
        query.orderBy(true, true, "menu_sort");


         List<SysMenu> menus=menuMapper.selectList(query);

         if(menus.size()>0){
             //一级菜单
             List<SysMenu> tops=menus.stream().filter(menu->menu.getParentId()==0L)
                     .collect(Collectors.toList());

             tops.forEach(menu->{
                  menu.setTabId(CommonUtil.getMenuTabId(menu.getMenuUrl()));
                 //二级菜单
                 long pid=menu.getId();
                 List<SysMenu> sons=menus.stream().filter(m->m.getParentId()==pid).collect(Collectors.toList());
                 sons.forEach(son->{
                     son.setTabId(CommonUtil.getMenuTabId(son.getMenuUrl()));
                     //三级菜单
                      long sonPid=son.getId();
                     List<SysMenu> sons2=menus.stream().filter(m->m.getParentId()==sonPid).collect(Collectors.toList());
                     sons2.forEach(s->{
                         s.setTabId(CommonUtil.getMenuTabId(s.getMenuUrl()));
                     });
                     son.setChildren(sons2);
                 });
                 menu.setChildren(sons);
             });

             return tops;
         }
        return menus;
        // return menuMapper.selectList(query);

    }


    /**
    *返回数据
     * @Author yushuo
     * @Description //TODO
     * @Date 14:04 2021/1/25
     * @Param []
     * @return java.util.List<com.easycms.domain.system.SysMenu>
    **/
    public List<SysMenu> getMenus(){

        QueryWrapper<SysMenu> query=new QueryWrapper<>();
        query.orderBy(true, true, "menu_sort");
        List<SysMenu> menus=menuMapper.selectList(query);

        return menus;

    }


    /**
     * 获取菜单下拉 格式化一下
     * @return
     */
    public List<KeyValueInt64Dto> getMenuSelect(){
        QueryWrapper<SysMenu> query=new QueryWrapper<>();
        //query.eq("menu_type",1)
       query.orderBy(true, true, "menu_sort");


        List<SysMenu> menus=menuMapper.selectList(query);
        
        List<KeyValueInt64Dto> menuSel=new ArrayList<>();
        menuSel.add(new KeyValueInt64Dto(0L,"请选择"));
        if(menus.size()>0){
            //一级菜单
            List<SysMenu> tops=menus.stream().filter(menu->menu.getParentId()==0L)
                    .collect(Collectors.toList());
            tops.forEach(menu->{
                KeyValueInt64Dto model=new KeyValueInt64Dto();
                model.setId(menu.getId());
                String name=StrUtil.format("¦┈┈{}", menu.getMenuName());
                model.setName(name);
                menuSel.add(model);
                //二级菜单
                long pid=menu.getId();
                List<SysMenu> sons=menus.stream().filter(m->m.getParentId()==pid).collect(Collectors.toList());
                sons.forEach(son->{
                    KeyValueInt64Dto model2=new KeyValueInt64Dto();
                    model2.setId(son.getId());
                    String name2=StrUtil.format("¦┄┄¦┄┄{}", son.getMenuName());
                    model2.setName(name2);
                    menuSel.add(model2);
                    //三级菜单
                     long sonPid=son.getId();
                    List<SysMenu> sons2=menus.stream().filter(m->m.getParentId()==sonPid).collect(Collectors.toList());
                    sons2.forEach(m->{
                        KeyValueInt64Dto model3=new KeyValueInt64Dto();
                        model3.setId(m.getId());
                        String name3=StrUtil.format("¦┄┄¦┄┄¦--{}", m.getMenuName());
                        model3.setName(name3);
                        menuSel.add(model3);
                    });
                });
              
            });

            
        }
       return menuSel;
    }


    /**
     * 获取菜单信息
     * @param id
     * @return
     */
    public MenuDto getMenuModel(String id){
        Long idl=Convert.toLong(id);
        QueryWrapper<SysMenu> query=new QueryWrapper<>();
        query.eq("id",idl);
        MenuDto model=new MenuDto();

        SysMenu menu=menuMapper.selectById(idl);
         if(menu==null){
             return null;
         }

         //操作信息
         LambdaQueryWrapper<SysOperate> fquery=new LambdaQueryWrapper<>();
         fquery.eq(SysOperate::getMenuId,menu.getId());
         List<SysOperate> funcs=operateMapper.selectList(fquery);
         model.setMenu(menu);
         if(funcs.size()>0){
             model.setFuncList(funcs);
         }

        return model;
    }

    /**
     * @Author yushuo
     * @Description //保存菜单和按钮信息
     * @Date 11:17 2021/1/25
     * @Param SysMenu [menuDto]
     * @return void
    **/
    public void saveMenu(SysMenu menuDto,String funcs){
        if(menuDto.getParentId()==0){
            menuDto.setMenuUrl("");
            if(StrUtil.isEmpty(menuDto.getMenuIcon())){
                menuDto.setMenuIcon("fa fa-desktop");
            }

        }else
        {
            if(StrUtil.isEmpty(menuDto.getMenuIcon())){
                menuDto.setMenuIcon("fa fa-tag");
            }
        }
        if(StrUtil.isEmpty(menuDto.getRoleTag())){
            menuDto.setRoleTag("");
        }
        if(menuDto.getId()==0){
            addMenu(menuDto,funcs);
        }else{
            updateMenu(menuDto,funcs);
        }
    }

    /**
    *
     * @Author yushuo
     * @Description //TODO
     * @Date 11:36 2021/1/25
     * @Param SysMenu [dto]
     * @return void
    **/
    @Transactional(rollbackFor =Exception.class )
    public void addMenu(SysMenu dto,String funcs){
        dto.setId(IdHelper.nextId());
        dto.setCreateTime(DateUtil.date());
        dto.setCreatePerson("yushuo");

        if(!StrUtil.isEmpty(dto.getMenuUrl())){
            dto.setMenuType(CommonUtil.byteTrue());
        }
        if (dto.getParentId() == 0)
        {
            dto.setMenuLevel(CommonUtil.byteTrue());
        }
        else
        {
            LambdaQueryWrapper<SysMenu> menuQuery=new LambdaQueryWrapper<>();
            menuQuery.eq(SysMenu::getId,dto.getParentId())
            .select(SysMenu::getMenuLevel);
            SysMenu menuLevel=menuMapper.selectOne(menuQuery);

            dto.setMenuLevel(menuLevel.getMenuLevel()+1);
        }

        menuMapper.insert(dto);
        //操作

        if(!StrUtil.isEmpty(funcs)){
            List<SysOperate> operates=new ArrayList<>();
           List<SysFuncDto> funcList= JSONUtil.toList(funcs,SysFuncDto.class);
           for (SysFuncDto func: funcList){
               SysOperate operate=new SysOperate();
               operate.setId(IdHelper.nextId());
                operate.setMenuId(dto.getId());
                operate.setFuncTitle(func.getTitle());
                operate.setFuncSort(func.getFuncSort());
                operate.setRoleTag(func.getRoleTag());
                operates.add(operate);
           }

           if(operates.size()>0){
               try{
                   operateMapper.insertBatch(operates);
               }catch (NullPointerException ex){
                   System.out.println(ex.getMessage());
               }

           }
        }
    }


    /**
    *
     * @author yushuo
     * @description //TODO
     * @date 14:37 2021/1/25
     * @param dto, funcs
     * @return void
    **/
    @Transactional(rollbackFor =Exception.class )
    public void updateMenu(SysMenu dto,String funcs){

        if(!StrUtil.isEmpty(dto.getMenuUrl())){
            dto.setMenuType(1);
        }
        if (dto.getParentId() == 0)
        {
            dto.setMenuLevel(1);
        }
        else
        {
            LambdaQueryWrapper<SysMenu> menuQuery=new LambdaQueryWrapper<>();
            menuQuery.eq(SysMenu::getId,dto.getParentId())
                    .select(SysMenu::getMenuLevel);
            SysMenu menuLevel=menuMapper.selectOne(menuQuery);
            dto.setMenuLevel(menuLevel.getMenuLevel()+1);
        }

        LambdaQueryWrapper<SysMenu> menuQuery=new LambdaQueryWrapper<>();
        menuQuery.eq(SysMenu::getId,dto.getId())
                .select(SysMenu::getMenuLevel);
        SysMenu menu=menuMapper.selectOne(menuQuery);
        dto.setCreatePerson(menu.getCreatePerson());
        dto.setCreateTime(menu.getCreateTime());
        //更新操作
        menuMapper.updateById(dto);

        //操作
        Map<String, Object> delMap=new HashMap<>(1);
        delMap.put("menu_id",dto.getId());
        operateMapper.deleteByMap(delMap);

        if(!StrUtil.isEmpty(funcs)){
            List<SysOperate> operates=new ArrayList<>();
            List<SysFuncDto> funcList= JSONUtil.toList(funcs,SysFuncDto.class);
            for (SysFuncDto func: funcList){
                SysOperate operate=new SysOperate();
                operate.setId(func.getId());
                operate.setMenuId(dto.getId());
                operate.setFuncTitle(func.getTitle());
                operate.setFuncSort(func.getFuncSort());
                operate.setRoleTag(func.getRoleTag());
                if(operate.getId()==0){
                    operate.setId(IdHelper.nextId());
                }
                operates.add(operate);
            }
            if(operates.size()>0){
                operateMapper.insertBatch(operates);
            }
        }
    }


    /**
    *
     * @author yushuo
     * @description 删除菜单和关联权限信息
     * @date 10:39 2021/1/29
     * @param
     * @return void
    **/
    @Transactional(rollbackFor = EasyException.class )
    public void delById(long id){
        SysMenu menu=menuMapper.selectById(id);
        if(menu==null){
            return;
        }
        LambdaQueryWrapper<SysMenu> menuQuery= Wrappers.lambdaQuery();
        menuQuery.eq(SysMenu::getParentId,id);
        int menuSonCount=menuMapper.selectCount(menuQuery);
        if(menuSonCount>0){
            throw  new EasyException("当成菜单下有子菜单，禁止删除");
        }

        Map map = new HashMap();
        map.put("parent_id",id);
         LambdaQueryWrapper<SysOperate> query=new LambdaQueryWrapper<>();
         query.eq(SysOperate::getMenuId,id);
        int count=operateMapper.selectCount(query);
        LambdaQueryWrapper<SysRoleAuthorize> roleAuthorQuery=Wrappers.lambdaQuery();
        if(count>0){
            //删除操作表
            operateMapper.delete(query);
            //删除权限关联操作
            roleAuthorQuery.eq(SysRoleAuthorize::getMenuPid,id);
            roleAuthorizeMapper.delete(roleAuthorQuery);
        }
        //删除菜单
        menuMapper.deleteById(id);
        //删除权限关联菜单
        roleAuthorQuery.clear();
        roleAuthorQuery.eq(SysRoleAuthorize::getMenuId,id);
        roleAuthorizeMapper.delete(roleAuthorQuery);


        //菜单有改动 删除全部权限缓存
        PermissionCache.clearAll();
    }


}
